﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Common
{
    /// <summary>
    /// 日志帮助类
    /// </summary>
    public class LOG
    {
        public static string _LogDir = @"D:\XWScada_Log\";
        /// <summary>
        /// 异常日志队列
        /// </summary>
        private static Queue<string> _queueEXLog = new Queue<string>();

        /// <summary>
        /// 流水日志队列
        /// </summary>
        private static Queue<string> _queueFLLog = new Queue<string>();

        /// <summary>
        /// 锁
        /// </summary>
        public static Object Locker = new object();

        /// <summary>
        /// 启动日志写入
        /// </summary>
        public static void Start()
        {
            if (string.IsNullOrEmpty(_LogDir))
            {
                _LogDir= @"D:\XWScada_Log\";
            }

            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    DeleteLogs(_LogDir + @"\ex\");
                    DeleteLogs(_LogDir + @"\fl\");
                    lock (_queueEXLog)
                    {
                        if (_queueEXLog.Count > 0)
                        {
                            string msg = _queueEXLog.Dequeue();
                            Log(_LogDir + @"\ex\", msg);
                        }
                    }

                    lock (_queueFLLog)
                    {
                        if (_queueFLLog.Count > 0)
                        {
                            string msg = _queueFLLog.Dequeue();
                            Log(_LogDir + @"\fl\", msg);
                        }
                    }
                }
            });
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="dir">目录</param>
        /// <param name="msg">文本</param>
        public static void Log(string dir,string msg)
        {
            try
            {
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                var log = new StreamWriter(dir + DateTime.Now.ToString("yyyy-MM-dd") + ".txt",true);
                log.Write(" ");
                log.Write(msg);
                log.Write("\r\n");
                log.Flush();
                log.Close();
            }
            catch(Exception ex)
            {

            }
        }

        /// <summary>
        /// 写异常日志
        /// </summary>
        /// <param name="msg"></param>
        public static void Write(Exception ex)
        {
            lock (_queueEXLog)
            {
                _queueEXLog.Enqueue(ex.StackTrace + ex.ToString());
            }
        }

        /// <summary>
        /// 加锁的方式写流水日志
        /// </summary>
        /// <param name="msg"></param>
        public static void Write(string msg,bool withLock=true)
        {
            if (withLock)
            {
                lock (Locker)
                {
                    WriteWithLock(msg);
                }
            }
            else
            {
                WriteWithLock(msg);
            }
        }

        /// <summary>
        /// 不加锁的方式写流水日志
        /// </summary>
        /// <param name="msg"></param>
        public static void WriteWithLock(string msg)
        {
            if (!string.IsNullOrEmpty(msg))
            {
                msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + msg;
            }

            Console.WriteLine(msg);
            lock (_queueFLLog)
            {
                _queueFLLog.Enqueue(msg);
            }
        }

        /// <summary>
        /// 仅写日志，不输出
        /// </summary>
        /// <param name="msg"></param>
        public static void WriteOnly(string msg)
        {
            if (!string.IsNullOrEmpty(msg))
            {
                msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + msg;
            }

            lock (_queueFLLog)
            {
                _queueFLLog.Enqueue(msg);
            }
        }

        /// <summary>
        /// 删除超过1年的日志文件
        /// </summary>
        /// <param name="dir"></param>
        private static void DeleteLogs(string dir)
        {
            int days = 365;

            try
            {
                if (!Directory.Exists(dir))
                {
                    return;
                }
                var now = DateTime.Now;
                foreach (var f in Directory.GetFileSystemEntries(dir).ToList().Where(f => File.Exists(f)))
                {
                    var t = File.GetCreationTime(f);
                    var elapsedTicks = now.Ticks - t.Ticks;
                    var elaspsedSpan = new TimeSpan(elapsedTicks);
                    if (elaspsedSpan.TotalDays > days)
                    {
                        File.Delete(f);
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}
